import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators} from '@angular/forms';
import { Router } from '@angular/router';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import {api} from "@core/service/config/api";
import {AuthService} from "@core/service/AuthService";
import {StatusCode} from "@shared/models/StatusCode";
import {NzMessageService} from "ng-zorro-antd/message";
declare function MatchControl(controlName: string, matchingControlName: string): ValidatorFn;
@Component({
  selector: 'passport-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class RegisterComponent implements OnDestroy,OnInit {
  constructor(
    fb: FormBuilder,
    private router: Router,
    private cdr: ChangeDetectorRef,
    private authService:AuthService,
    private message: NzMessageService
  ) {
    let self = this;
    this.form = fb.group(
      {
        mail: [null, [Validators.required, Validators.email]],
        password: [null, [Validators.required, Validators.minLength(6), RegisterComponent.checkPassword.bind(this)]],
        confirm: [null, [Validators.required,(control: FormControl) => (control.value != self.form?.controls.password.value)? { msg: '两次输入的密码不一致！'} : null]],
        // usernamePrefix: ['+86'],
        username: [null, [Validators.required,Validators.pattern(/^([\u4e00-\u9fa5]{2,4})|([A-Za-z0-9_]{4,16})|([a-zA-Z0-9_\u4e00-\u9fa5]{3,16})$/)]],
        captchaMail: [null, [Validators.required]],
        captchaImg: [null, [Validators.required]]
      },
      {
        // validators: MatchControl('password', 'confirm')
      }
    );
  }

  ngOnInit(): void {
    this.flashImgCaptcha()
  }

  // #region fields

  get mail(): AbstractControl {
    return this.form.controls.mail;
  }
  get password(): AbstractControl {
    return this.form.controls.password;
  }
  get confirm(): AbstractControl {
    return this.form.controls.confirm;
  }
  get username(): AbstractControl {
    return this.form.controls.username;
  }
  get captchaImg(): AbstractControl {
    return this.form.controls.captchaImg;
  }
  get captchaMail(): AbstractControl {
    return this.form.controls.captchaMail;
  }
  isSendMail = false;
  form: FormGroup;
  error = '';
  type = 0;
  loading = false;
  visible = false;
  status = 'pool';
  progress = 0;
  captcha_id = '0';
  passwordProgressMap: { [key: string]: 'success' | 'normal' | 'exception' } = {
    ok: 'success',
    pass: 'normal',
    pool: 'exception'
  };

  // #endregion

  // #region get captcha

  count = 0;
  interval$: any;

  static checkPassword(control: FormControl): NzSafeAny {
    if (!control) {
      return null;
    }
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const self: any = this;
    self.visible = !!control.value;
    if (control.value && control.value.length > 9) {
      self.status = 'ok';
    } else if (control.value && control.value.length > 5) {
      self.status = 'pass';
    } else {
      self.status = 'pool';
    }

    if (self.visible) {
      self.progress = control.value.length * 10 > 100 ? 100 : control.value.length * 10;
    }
  }

  getEmailCaptcha(): void {
    if (this.mail.invalid) {
      this.mail.markAsDirty({ onlySelf: true });
      this.mail.updateValueAndValidity({ onlySelf: true });
      return;
    }
    let that = this;
    let data = {
      email:this.mail.value,
      imgId:this.captcha_id,
      imgValue:this.captchaImg.value
    }
    that.count = 60;
    let messageId =this.message.loading('邮件发送中...',{ nzDuration: 0 }).messageId;
    this.authService.sendEmailCaptcha(data)
      .subscribe((res:any)=>{
        console.log('发送邮件结果：',res);
        that.message.remove(messageId);
        if (res.code != 200){
          that.message.error(res.msg, { nzDuration: 2500 });
          if (res.code==StatusCode.CAPTCHA_ERROR){
            that.captchaImg.setErrors({msg:res.msg});
          }else {
            that.error = res.msg;
          }
          that.flashImgCaptcha();
          return;
        }
        that.message.success('邮件已发送！', { nzDuration: 2500 });
        that.isSendMail=true;
        that.cdr.detectChanges();
        that.interval$ = setInterval(() => {
          that.count -= 1;
          that.cdr.detectChanges();
          if (that.count <= 0) {
            clearInterval(that.interval$);
          }
        }, 1000);
      },(msg)=>{that.error='网络连接失败'})
  }

  // #endregion

  submit(): void {
    this.error = '';
    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
      this.form.controls[key].updateValueAndValidity();
    });
    if (this.form.invalid) {
      return;
    }
    const data1 = this.form.value;
    const data = {
      captcha:data1.captchaMail,
      username:data1.username,
      email:data1.mail,
      password:data1.password
    }
    this.loading = true;
    this.cdr.detectChanges();
    console.log(data)
    const that = this;
    this.authService.register(data)
      .subscribe((res:any)=>{
        switch (res.code){
          case StatusCode.OK: that.router.navigateByUrl("/registerSuccess",{replaceUrl:true}); break
          case StatusCode.MAIL_ERROR: that.mail.setErrors({msg:res.msg}); break
          case StatusCode.CAPTCHA_ERROR: that.captchaMail.setErrors({msg:res.msg}); break
        }
        that.loading = false;
        that.flashImgCaptcha();
        that.cdr.detectChanges();

      },(msg)=>{
        that.error='网络连接失败';
        this.loading = false;
        this.cdr.detectChanges();
      })
  }

  ngOnDestroy(): void {
    if (this.interval$) {
      clearInterval(this.interval$);
    }
  }

  flashImgCaptcha() {
    let captchaImg:any = document.getElementById("captchaImg");
    if (captchaImg) {
      this.captcha_id = new Date().getTime()+""+(Math.random()*1000).toFixed(0)
      captchaImg.src=api.captchaImg+"/"+this.captcha_id;
    }
  }

  checkUsername() {
    console.log('checkUsername:',this.username.value);
    let that = this;
    if (this.username.invalid){
      return;
    }
    this.authService
      .checkUsername(this.username.value).subscribe((res:any)=>{
        console.log(res)
        if (res.code != 200){
          that.username.setErrors({msg:res.msg})
        }
    })
  }
  checkEmail() {
    console.log('checkEmail:',this.mail.value);
    let that = this;
    if (this.mail.invalid){
      return;
    }
    this.authService
      .checkEmail(this.mail.value).subscribe((res:any)=>{
      console.log(res)
      if (res.code != 200){
        that.mail.setErrors({msg:res.msg})
      }
    })
  }
}
